#!/bin/bash

# 通用后台管理系统 - 自动化部署脚本
# 适用于 Debian 12 系统
# 作者：高职教师
# 版本：1.0

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 配置变量
PROJECT_NAME="universal-admin"
PROJECT_DIR="/opt/${PROJECT_NAME}"
NGINX_CONF="/etc/nginx/sites-available/${PROJECT_NAME}"
SYSTEMD_SERVICE="/etc/systemd/system/${PROJECT_NAME}.service"
DB_NAME="universal_admin"
DB_USER="admin_user"
DB_PASSWORD="UniversalAdmin@2024"
FRONTEND_PORT=3000
BACKEND_PORT=5000

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_step() {
    echo -e "${BLUE}[STEP]${NC} $1"
}

# 检查是否为root用户
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本必须以root用户运行"
        exit 1
    fi
}

# 检查系统版本
check_system() {
    log_step "检查系统版本..."
    
    if ! grep -q "Debian GNU/Linux 12" /etc/os-release; then
        log_warn "此脚本专为Debian 12设计，其他系统可能存在兼容性问题"
    fi
    
    log_info "系统检查完成"
}

# 更新系统
update_system() {
    log_step "更新系统包..."
    
    apt update && apt upgrade -y
    apt install -y curl wget gnupg2 software-properties-common apt-transport-https
    
    log_info "系统更新完成"
}

# 安装PostgreSQL
install_postgresql() {
    log_step "安装PostgreSQL..."
    
    if ! command -v psql &> /dev/null; then
        apt install -y postgresql postgresql-contrib
        systemctl enable postgresql
        systemctl start postgresql
        
        log_info "PostgreSQL安装完成"
    else
        log_info "PostgreSQL已安装"
    fi
}

# 配置PostgreSQL
configure_postgresql() {
    log_step "配置PostgreSQL..."
    
    # 创建数据库用户
    sudo -u postgres createuser --createdb --login --pwprompt ${DB_USER} || true
    
    # 创建数据库
    sudo -u postgres createdb -O ${DB_USER} ${DB_NAME} || true
    
    # 配置pg_hba.conf允许密码认证
    PG_VERSION=$(sudo -u postgres psql -c "SELECT version();" | grep -oP 'PostgreSQL \K[0-9]+\.[0-9]+')
    PG_HBA_FILE="/etc/postgresql/${PG_VERSION}/main/pg_hba.conf"
    
    if ! grep -q "local.*${DB_NAME}.*${DB_USER}.*md5" ${PG_HBA_FILE}; then
        echo "local   ${DB_NAME}     ${DB_USER}                     md5" >> ${PG_HBA_FILE}
        systemctl restart postgresql
    fi
    
    log_info "PostgreSQL配置完成"
}

# 安装Node.js
install_nodejs() {
    log_step "安装Node.js..."
    
    if ! command -v node &> /dev/null; then
        curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
        apt install -y nodejs
        
        # 安装pnpm
        npm install -g pnpm
        
        log_info "Node.js安装完成"
    else
        log_info "Node.js已安装"
    fi
}

# 安装.NET 8
install_dotnet() {
    log_step "安装.NET 8..."
    
    if ! command -v dotnet &> /dev/null; then
        # 添加Microsoft包源
        wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
        dpkg -i packages-microsoft-prod.deb
        rm packages-microsoft-prod.deb
        
        # 安装.NET 8
        apt update
        apt install -y dotnet-sdk-8.0
        
        log_info ".NET 8安装完成"
    else
        log_info ".NET 8已安装"
    fi
}

# 安装Nginx
install_nginx() {
    log_step "安装Nginx..."
    
    if ! command -v nginx &> /dev/null; then
        apt install -y nginx
        systemctl enable nginx
        systemctl start nginx
        
        log_info "Nginx安装完成"
    else
        log_info "Nginx已安装"
    fi
}

# 创建项目目录
create_project_dirs() {
    log_step "创建项目目录..."
    
    mkdir -p ${PROJECT_DIR}/frontend
    mkdir -p ${PROJECT_DIR}/backend
    mkdir -p ${PROJECT_DIR}/scripts
    mkdir -p ${PROJECT_DIR}/logs
    mkdir -p ${PROJECT_DIR}/uploads
    
    log_info "项目目录创建完成"
}

# 初始化数据库
init_database() {
    log_step "初始化数据库..."
    
    # 检查数据库初始化脚本是否存在
    if [[ -f "./scripts/database-init.sql" ]]; then
        sudo -u postgres psql -d ${DB_NAME} -f ./scripts/database-init.sql
        log_info "数据库初始化完成"
    else
        log_warn "数据库初始化脚本不存在，跳过数据库初始化"
    fi
}

# 部署前端
deploy_frontend() {
    log_step "部署前端应用..."
    
    if [[ -d "./frontend" ]]; then
        cp -r ./frontend/* ${PROJECT_DIR}/frontend/
        
        cd ${PROJECT_DIR}/frontend
        
        # 安装依赖
        pnpm install
        
        # 构建项目
        pnpm run build
        
        log_info "前端应用构建完成"
    else
        log_warn "前端目录不存在，跳过前端部署"
    fi
}

# 部署后端
deploy_backend() {
    log_step "部署后端应用..."
    
    if [[ -d "./backend" ]]; then
        cp -r ./backend/* ${PROJECT_DIR}/backend/
        
        cd ${PROJECT_DIR}/backend
        
        # 还原NuGet包
        dotnet restore
        
        # 构建项目
        dotnet build --configuration Release
        
        # 发布项目
        dotnet publish --configuration Release --output ${PROJECT_DIR}/backend/publish
        
        log_info "后端应用构建完成"
    else
        log_warn "后端目录不存在，跳过后端部署"
    fi
}

# 创建systemd服务
create_systemd_service() {
    log_step "创建systemd服务..."
    
    cat > ${SYSTEMD_SERVICE} << EOF
[Unit]
Description=Universal Admin System Backend
After=network.target

[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=${PROJECT_DIR}/backend/publish
ExecStart=/usr/bin/dotnet ${PROJECT_DIR}/backend/publish/UniversalAdmin.Api.dll
Restart=always
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=universal-admin
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target
EOF
    
    systemctl daemon-reload
    systemctl enable ${PROJECT_NAME}
    
    log_info "systemd服务创建完成"
}

# 配置Nginx
configure_nginx() {
    log_step "配置Nginx..."
    
    cat > ${NGINX_CONF} << EOF
server {
    listen 80;
    server_name _;
    
    # 前端静态文件
    location / {
        root ${PROJECT_DIR}/frontend/dist;
        index index.html index.htm;
        try_files \$uri \$uri/ /index.html;
    }
    
    # 后端API代理
    location /api/ {
        proxy_pass http://localhost:${BACKEND_PORT};
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_cache_bypass \$http_upgrade;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
    
    # 文件上传
    location /uploads/ {
        alias ${PROJECT_DIR}/uploads/;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # 日志配置
    access_log ${PROJECT_DIR}/logs/nginx_access.log;
    error_log ${PROJECT_DIR}/logs/nginx_error.log;
}
EOF
    
    # 启用站点
    ln -sf ${NGINX_CONF} /etc/nginx/sites-enabled/
    
    # 删除默认站点
    rm -f /etc/nginx/sites-enabled/default
    
    # 测试配置
    nginx -t
    
    # 重启Nginx
    systemctl restart nginx
    
    log_info "Nginx配置完成"
}

# 设置权限
set_permissions() {
    log_step "设置文件权限..."
    
    chown -R www-data:www-data ${PROJECT_DIR}
    chmod -R 755 ${PROJECT_DIR}
    chmod -R 775 ${PROJECT_DIR}/uploads
    chmod -R 775 ${PROJECT_DIR}/logs
    
    log_info "文件权限设置完成"
}

# 创建多用户部署脚本
create_multi_user_deploy() {
    log_step "创建多用户部署脚本..."
    
    cat > ${PROJECT_DIR}/scripts/deploy-multi-user.sh << 'EOF'
#!/bin/bash

# 多用户部署脚本
# 为每个组员创建独立的访问地址

USERS=("user1" "user2" "user3" "user4" "user5")
BASE_PORT=5000
FRONTEND_BASE_PORT=3000
PROJECT_DIR="/opt/universal-admin"

for i in "${!USERS[@]}"; do
    USER=${USERS[$i]}
    BACKEND_PORT=$((BASE_PORT + i))
    FRONTEND_PORT=$((FRONTEND_BASE_PORT + i))
    
    echo "部署用户: $USER"
    echo "后端端口: $BACKEND_PORT"
    echo "前端端口: $FRONTEND_PORT"
    
    # 创建用户目录
    mkdir -p ${PROJECT_DIR}/users/${USER}
    
    # 复制后端文件
    cp -r ${PROJECT_DIR}/backend/publish ${PROJECT_DIR}/users/${USER}/backend
    
    # 创建用户配置文件
    cat > ${PROJECT_DIR}/users/${USER}/backend/appsettings.Production.json << USEREOF
{
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Database=universal_admin_${USER};Username=admin_user;Password=UniversalAdmin@2024"
  },
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:${BACKEND_PORT}"
      }
    }
  }
}
USEREOF
    
    # 创建systemd服务
    cat > /etc/systemd/system/universal-admin-${USER}.service << SERVICEEOF
[Unit]
Description=Universal Admin System Backend for ${USER}
After=network.target

[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=${PROJECT_DIR}/users/${USER}/backend
ExecStart=/usr/bin/dotnet ${PROJECT_DIR}/users/${USER}/backend/UniversalAdmin.Api.dll
Restart=always
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=universal-admin-${USER}
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target
SERVICEEOF
    
    # 启用服务
    systemctl enable universal-admin-${USER}
    systemctl start universal-admin-${USER}
    
    # 创建Nginx配置
    cat > /etc/nginx/sites-available/universal-admin-${USER} << NGINXEOF
server {
    listen 80;
    server_name ${USER}.localhost;
    
    location / {
        root ${PROJECT_DIR}/frontend/dist;
        index index.html index.htm;
        try_files \$uri \$uri/ /index.html;
    }
    
    location /api/ {
        proxy_pass http://localhost:${BACKEND_PORT};
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_cache_bypass \$http_upgrade;
    }
    
    access_log ${PROJECT_DIR}/logs/nginx_${USER}_access.log;
    error_log ${PROJECT_DIR}/logs/nginx_${USER}_error.log;
}
NGINXEOF
    
    # 启用站点
    ln -sf /etc/nginx/sites-available/universal-admin-${USER} /etc/nginx/sites-enabled/
    
    # 创建用户数据库
    sudo -u postgres createdb -O admin_user universal_admin_${USER} || true
    
    echo "用户 $USER 部署完成"
    echo "访问地址: http://${USER}.localhost"
    echo "---"
done

# 重启Nginx
systemctl restart nginx

echo "多用户部署完成！"
echo "请在客户端hosts文件中添加以下记录："
echo "127.0.0.1 user1.localhost"
echo "127.0.0.1 user2.localhost"
echo "127.0.0.1 user3.localhost"
echo "127.0.0.1 user4.localhost"
echo "127.0.0.1 user5.localhost"
EOF
    
    chmod +x ${PROJECT_DIR}/scripts/deploy-multi-user.sh
    
    log_info "多用户部署脚本创建完成"
}

# 创建备份脚本
create_backup_script() {
    log_step "创建备份脚本..."
    
    cat > ${PROJECT_DIR}/scripts/backup.sh << 'EOF'
#!/bin/bash

# 备份脚本
BACKUP_DIR="/opt/universal-admin/backups"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="universal_admin"
DB_USER="admin_user"

# 创建备份目录
mkdir -p ${BACKUP_DIR}

# 备份数据库
echo "备份数据库..."
sudo -u postgres pg_dump -U ${DB_USER} ${DB_NAME} > ${BACKUP_DIR}/database_${DATE}.sql

# 备份上传文件
echo "备份上传文件..."
tar -czf ${BACKUP_DIR}/uploads_${DATE}.tar.gz -C /opt/universal-admin uploads

# 备份配置文件
echo "备份配置文件..."
tar -czf ${BACKUP_DIR}/config_${DATE}.tar.gz /etc/nginx/sites-available/universal-admin /etc/systemd/system/universal-admin.service

# 清理7天前的备份
find ${BACKUP_DIR} -name "*.sql" -mtime +7 -delete
find ${BACKUP_DIR} -name "*.tar.gz" -mtime +7 -delete

echo "备份完成: ${BACKUP_DIR}"
EOF
    
    chmod +x ${PROJECT_DIR}/scripts/backup.sh
    
    # 添加到crontab
    (crontab -l 2>/dev/null; echo "0 2 * * * ${PROJECT_DIR}/scripts/backup.sh") | crontab -
    
    log_info "备份脚本创建完成"
}

# 创建监控脚本
create_monitor_script() {
    log_step "创建监控脚本..."
    
    cat > ${PROJECT_DIR}/scripts/monitor.sh << 'EOF'
#!/bin/bash

# 系统监控脚本
PROJECT_DIR="/opt/universal-admin"
LOG_FILE="${PROJECT_DIR}/logs/monitor.log"

# 检查服务状态
check_service() {
    local service_name=$1
    if systemctl is-active --quiet $service_name; then
        echo "$(date): $service_name is running" >> $LOG_FILE
        return 0
    else
        echo "$(date): $service_name is not running, attempting to restart" >> $LOG_FILE
        systemctl restart $service_name
        return 1
    fi
}

# 检查端口
check_port() {
    local port=$1
    if netstat -tlnp | grep -q ":$port "; then
        echo "$(date): Port $port is open" >> $LOG_FILE
        return 0
    else
        echo "$(date): Port $port is not open" >> $LOG_FILE
        return 1
    fi
}

# 检查磁盘空间
check_disk() {
    local usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
    if [ $usage -gt 80 ]; then
        echo "$(date): Disk usage is high: $usage%" >> $LOG_FILE
        echo "High disk usage: $usage%" | mail -s "Server Alert" admin@example.com
    fi
}

# 检查内存使用
check_memory() {
    local usage=$(free | grep Mem | awk '{printf "%.0f", $3/$2 * 100.0}')
    if [ $usage -gt 80 ]; then
        echo "$(date): Memory usage is high: $usage%" >> $LOG_FILE
    fi
}

# 主检查流程
echo "$(date): Starting system check" >> $LOG_FILE

check_service "universal-admin"
check_service "nginx"
check_service "postgresql"
check_port "80"
check_port "5000"
check_disk
check_memory

echo "$(date): System check completed" >> $LOG_FILE
EOF
    
    chmod +x ${PROJECT_DIR}/scripts/monitor.sh
    
    # 添加到crontab（每5分钟检查一次）
    (crontab -l 2>/dev/null; echo "*/5 * * * * ${PROJECT_DIR}/scripts/monitor.sh") | crontab -
    
    log_info "监控脚本创建完成"
}

# 启动服务
start_services() {
    log_step "启动服务..."
    
    systemctl start ${PROJECT_NAME}
    systemctl restart nginx
    
    log_info "服务启动完成"
}

# 显示部署信息
show_deployment_info() {
    log_step "部署信息"
    
    echo "========================================"
    echo "       部署完成信息"
    echo "========================================"
    echo "项目目录: ${PROJECT_DIR}"
    echo "数据库: ${DB_NAME}"
    echo "数据库用户: ${DB_USER}"
    echo "前端访问: http://localhost"
    echo "后端API: http://localhost/api"
    echo "系统服务: systemctl status ${PROJECT_NAME}"
    echo "Nginx配置: ${NGINX_CONF}"
    echo "========================================"
    echo "管理命令:"
    echo "  启动服务: systemctl start ${PROJECT_NAME}"
    echo "  停止服务: systemctl stop ${PROJECT_NAME}"
    echo "  重启服务: systemctl restart ${PROJECT_NAME}"
    echo "  查看日志: journalctl -u ${PROJECT_NAME} -f"
    echo "  多用户部署: ${PROJECT_DIR}/scripts/deploy-multi-user.sh"
    echo "  备份数据: ${PROJECT_DIR}/scripts/backup.sh"
    echo "========================================"
    echo "默认登录信息:"
    echo "  用户名: admin"
    echo "  密码: admin123"
    echo "========================================"
}

# 主部署流程
main() {
    log_info "开始部署通用后台管理系统..."
    
    check_root
    check_system
    update_system
    install_postgresql
    configure_postgresql
    install_nodejs
    install_dotnet
    install_nginx
    create_project_dirs
    init_database
    deploy_frontend
    deploy_backend
    create_systemd_service
    configure_nginx
    set_permissions
    create_multi_user_deploy
    create_backup_script
    create_monitor_script
    start_services
    show_deployment_info
    
    log_info "部署完成！"
}

# 检查参数
case "$1" in
    "install")
        main
        ;;
    "update")
        log_info "更新部署..."
        deploy_frontend
        deploy_backend
        systemctl restart ${PROJECT_NAME}
        systemctl restart nginx
        log_info "更新完成！"
        ;;
    "multi-user")
        log_info "执行多用户部署..."
        ${PROJECT_DIR}/scripts/deploy-multi-user.sh
        ;;
    "backup")
        log_info "执行备份..."
        ${PROJECT_DIR}/scripts/backup.sh
        ;;
    "monitor")
        log_info "执行监控检查..."
        ${PROJECT_DIR}/scripts/monitor.sh
        ;;
    "status")
        log_info "检查服务状态..."
        systemctl status ${PROJECT_NAME}
        systemctl status nginx
        systemctl status postgresql
        ;;
    "logs")
        log_info "查看应用日志..."
        journalctl -u ${PROJECT_NAME} -f
        ;;
    *)
        echo "使用方法: $0 {install|update|multi-user|backup|monitor|status|logs}"
        echo ""
        echo "  install     - 完整安装部署"
        echo "  update      - 更新部署"
        echo "  multi-user  - 多用户部署"
        echo "  backup      - 备份数据"
        echo "  monitor     - 监控检查"
        echo "  status      - 查看状态"
        echo "  logs        - 查看日志"
        exit 1
        ;;
esac
